<template>
    <Transition 
        :name="transitionName"
        @after-leave="destroyComponent"
        @enter="updateHeight">
        <div 
            v-show="visible"
            class="gems-message"
            :class="{[`gems-message--${type}`]: type, 'is-close': showClose}"
            role="alert"
            ref="messageRef"
            :style="cssStyle"
            @mouseenter="closeTimer"
            @mouseleave="startTimer"
        >
            <div class="gems-message__content">
                <slot>
                    <RenderVnode :vnode="message" v-if="message"/>
                    
                </slot>
            </div>
            <div class="gems-message__close" v-if="showClose">
                <Icon icon="xmark" @click.stop="visible = false" />
            </div>
        </div>
    </Transition>
</template>

<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import Icon from '../Icon/Icon.vue'
import RenderVnode from '../Common/RenderVnode'
import type { MessageProps } from './types'
import { getLastInstanceBottomOffset } from './method'
import useEventListener from '../../hooks/useEventListener'

defineOptions({
    name: 'GemsMessage',
})
const props = withDefaults(defineProps<MessageProps>(), {
    type: 'info',
    duration: 3000,
    offset: 20,
    transitionName: 'fade-up',
})
const messageRef = ref<HTMLDivElement>()
const visible = ref(false)

// 计算高度偏移
// 这个div组件高度
const height = ref(0)
// 上一个组件实例最下面的高度BottomOffset
const lastBottomOffset = computed(() => getLastInstanceBottomOffset(props.id!))
// 当前组件实例应该使用的topOffset
const topOffset = computed(() => lastBottomOffset.value + props.offset)
// 当前组件实例的bottomOffset
const bottomOffset = computed(() => topOffset.value + height.value)
// 当前组件实例的样式
const cssStyle = computed(() => ({
    top: `${topOffset.value}px`,
    zIndex: props.zIndex,
}))

// 定时器 -- 鼠标移出时，打开定时器
let timer : any 
function startTimer() {
    if (props.duration === 0) return
    timer = setTimeout(() => {
        visible.value = false
    }, props.duration);
}

// 鼠标移入 -- 关闭定时器
function closeTimer(){
    clearTimeout(timer)
}
 
onMounted(async() => {
    visible.value = true
    startTimer()
    // 等待组件渲染完成
    // await nextTick() 
    // // 获取组件高度  -- 换成updateHeight（） 更符合逻辑
    // height.value = messageRef.value!.getBoundingClientRect().height
    // 触发全局事件
})

// 键盘事件--按下Esc时，关闭Message
function handleKeydown(e: Event) {
    const event = e as KeyboardEvent
    if (event.code === 'Escape') {
        visible.value = false
    }
}
useEventListener(document, 'keydown', handleKeydown)

// 这种方式销毁会导致transition动画失效
// watch(visible, (newVal) => {
//     if (!newVal) {
//         // 销毁Message实例
//         props.onDestory();
//     }
// })

function destroyComponent () {
  props.onDestory()
}
function updateHeight() {
  height.value = messageRef.value!.getBoundingClientRect().height
}

defineExpose({
    bottomOffset,
    visible,
})


</script>